﻿using LEE.AspNetCore.Extensions.Swagger;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Swashbuckle.AspNetCore.Swagger;
using Swashbuckle.AspNetCore.SwaggerUI;
using System;
using System.Collections.Generic;
using System.Text;

namespace LEE.AspNetCore.Extensions.Swaggers
{
    /// <summary>
    /// swagger文档扩展
    /// </summary>
    public static class SwaggerServiceExtensions
    {
        /// <summary>
        /// 添加Swagger Api文档
        /// </summary>
        /// <param name="services"></param>
        /// <param name="setupAction"></param>
        /// <returns></returns>
        public static IServiceCollection AddSwaggerDocumentation(this IServiceCollection services, Action<AddSwaggerOptions> setupAction)
        {
            var options = new AddSwaggerOptions();
            setupAction?.Invoke(options);
            services.AddSwaggerGen(c =>
            {
                c.CustomSchemaIds(type => type.FullName);
                c.SwaggerDoc(options.Version, new Info { Title = options.Title, Version = options.Version });
                if (!string.IsNullOrWhiteSpace(options.XmlPath))
                {
                    c.IncludeXmlComments(options.XmlPath);
                }
                if (options.Headers != null && options.Headers.Count > 0)
                {
                    c.OperationFilter<AddHeaderOperationFilter>(options.Headers);
                }
                if (options.AddAuthorization)
                {
                    // Swagger 2.+ support
                    var security = new Dictionary<string, IEnumerable<string>>
                    {
                        {"Bearer", new string[] { }},
                    };

                    c.AddSecurityDefinition("Bearer", new ApiKeyScheme
                    {
                        Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"",
                        Name = "Authorization",
                        In = "header",
                        Type = "apiKey"
                    });
                    c.AddSecurityRequirement(security);
                }
            });

            return services;
        }

        public static IApplicationBuilder UseSwaggerDocumentation(this IApplicationBuilder app, Action<EndpointOption> endpointOption = null)
        {
            EndpointOption option = new EndpointOption();
            endpointOption?.Invoke(option);
            app.UseSwagger();
            app.UseSwaggerUI(c =>
            {
                c.SwaggerEndpoint(option.Url, option.Name);
                if (!string.IsNullOrEmpty(option.DocumentTitle))
                {
                    c.DocumentTitle = option.DocumentTitle;
                }
                c.DocExpansion(DocExpansion.None);
            });

            return app;
        }
    }
}
